simetrix.GroupVector

class simetrix.GroupVector(groupName: str = '', vectorName: str = '')

Bases: object

The GroupVector class is the main class used to access SIMetrix and SIMPLIS simulation data.

The GroupVector object references data stored in SIMetrix as a SIMetrix vector. These include but are not limited to data generated by simulation analyses. Data stored in SIMetrix script variables are also vectors and stored in the same way.

SIMetrix vectors, which GroupVector objects reference, can store both x and y data values. For example, a voltage vector created by a transient simulation would store both the voltage (y) values and the time (x) values. They also store the physical type of the data (e.g. volts, amps, seconds etc). Finally, for multi-step simulations such as Monte Carlo analyses, SIMetrix vectors can store multi-division data. All of these elements of SIMetrix vectors can be accessed in Python using the GroupVector object.

A GroupVector object in Python does not store any data itself; instead it holds a group name and a vector name which uniquely references the data stored in SIMetrix. GroupVector methods may be used to access that data either as Python lists or numpy arrays. As numpy arrays it is possible to access the raw SIMetrix data directly without requiring copying. This allows fast and efficient access to huge vectors with maybe hundreds of millions of data points.

GroupVector supports indexing, iteration and the len() function returning y-data for division 0.

Accessing Data from a GroupVector Object

There are two methods to obtain data from a GroupVector object

  1. Using GroupVector[div].ydata and GroupVector[div].xdata to obtain Python lists of float, complex and string data. ‘div’ is the division index.

  2. Loading a numPy array using the GroupVector[div].y and GroupVector[div].x. ‘div’ is the division index.

The first method is usually a little simpler and is adequate for vectors with fewer than around 10,000 points. It is also the only method to access string data. The second method is much faster especially for massive data vectors.

Accessing Data as Python Lists

GroupVector objects can write data to Python lists of float, complex or string values using the GroupVector.ydata and GroupVector.xdata properties.

The following example shows how to obtain the y-data and x-data (time) of a vector called “VOUT” obtained from a transient analysis:

import simetrix as sx
vector = sx.currentGroup().vectorOfName("VOUT")
# get division 0 of ydata
vout = vector[0].ydata
# get division 0 of xdata
time = vector[0].xdata

In the above the Python variables vout and time will be lists of float values. However, the above can take around 10 seconds to execute if “VOUT” has 50 million data points. For vectors larger than around 10,000 data points, it is more efficient to use numPy arrays.

Accessing Data as numPy arrays

GroupVector objects can load numpy arrays directly. For example:

import numpy as np
import simetrix as sx
vector = sx.currentGroup().vectorOfName("VOUT")
vout = np.array(vector[0].y)
time = np.array(vector[0].x)

The above takes around 0.3 seconds to execute for 50 million data points. Note that in the above case the data from SIMetrix is being copied to the numPy array. That is two new memory allocations are created each with the capacity for 50 million data points; the SIMetrix data is then copied to them. There is an option to instead access the data in memory directly as follows:

import numpy as np
import simetrix as sx
vector = sx.currentGroup().vectorOfName("VOUT")
vout = np.array(vector[0].y, copy=False)
time = np.array(vector[0].x, copy=False)

As long as the SIMetrix data has already been retrieved from disc, the above executes instantaneously as numPy is accessing the SIMetrix data directly in memory. If the data being accessed is not already in memory but instead resides on disc, there will be a delay while the data is retrieved from disc. But that is a one-off operation and any subsequent accesses will be instantaneous.

Note that care must be taken when using this method. If the SIMetrix data is deleted before the Python script completes and the Python script uses that data, a memory access violation will be triggered with possible program instability following. Further, Python will now be using the same memory locations for the data as SIMetrix. If the data is modified in Python, the data is SIMetrix will also be modified. Data retrieved using the above method should be treated as read-only.

Accessing Multi-division Data

For details on multi-division vectors see Multi-division Vectors. The above example demonstrates accessing division 0, which is the index of the ydata, xdata, y and x properties. For other divisions set the index to the division required. For example for the division 4:

vector[4].ydata
vector[4].xdata
vector[4].y
vector[4].x

Examples

In this example we run an AC simulation on a schematic then use Python code to search for the first simulation point below -3dB.

import simetrix as sx
import numpy as np

# Open aschematic
schematic = sx.openSchematic("%DOCSPATH%/SIMetrix/Examples-94/SIMetrix/General/AMP.sxsch")

if schematic.valid :

    # Run an AC analysis
    result = schematic.run([], [".ac dec 500 1k 100000000"])

    if result.status==sx.RunStatus.success :

        # get the data group
        dataGroup = result.primaryGroup

        # get the GroupVector object
        vector = dataGroup.vectorOfName("Vout")

        # Get the y-data. np.array(vector) returns the same result
        ydata = np.array(vector[0].y)
        xdata = np.array(vector[0].x)

        # Get db data
        data_db = 20*np.log10(abs(ydata))

        # Get the maximum value in dB
        peak_mag_db = np.max(data_db)

        # Get the -3dB point
        target_db = peak_mag_db - 3

        # Get the indices where the data is below the -3dB point
        indices = np.where(data_db < target_db)[0]

        # Print the frequency of the first point below -3dB
        if len(indices) > 0:
            print("-3db point:", xdata[indices[0]])

    else :
        print(result.status)
        print(result.errorMessage)

else :
    print("There are no schematics open")

See also

DataGroup

Methods

Create(y, x[, yPhysicalType, xPhysicalType])

Creates a GroupVector with the data provided.

assign(yval[, xval])

Assigns a value to a GroupVector.

Attributes

bool

Scalar single division value.

complex

Scalar single division value.

int

Scalar single division value.

name

Returns the name of the object.

numDivisions

Returns the number of divisions.

real

Scalar single division value.

ref

Returns the name of the object prefixed with '@'.

string

Scalar single division value.

stringdata

String data.

valid

Returns true if the GroupVector is valid, that is it exists in the SIMetrix environment

x

VectorData object for x values.

xcomplex

Complex x-data of division zero.

xdata

List of x values for division zero.

xreal

Real x-data of division zero.

y

VectorData object for y values.

ycomplex

Complex y-data of division zero.

ydata

List of y values for division zero.

yreal

Real y-data of division zero.

static Create(y: ArrayLike, x: ArrayLike, yPhysicalType: PhysicalType = PhysicalType.UNKNOWN, xPhysicalType: PhysicalType = PhysicalType.UNKNOWN) GroupVector

Creates a GroupVector with the data provided. This function creates the required data in SIMetrix then returns a GroupVector object that references the SIMetrix data.

This function can accept numpy arrays as arguments as well as Python lists.

Example

import simetrix as sx

vmag = [(-5.943112+0.0283819j),(-5.942828+0.0566276j),(-5.941697+0.1129733j),\
(-5.937198+0.2253031j),(-5.919322+0.4486815j),(-5.848743+0.8884801j),\
(-5.576729+1.7207099j),(-4.619714+3.0656445j),(-2.128718+4.1556888j),\
(0.8907083+2.8707831j),(1.2792536+0.4193534j)]

freq = [10000, 19952.623, 39810.717, 79432.823, 158489.32, 316227.77,\
630957.34, 1258925.4, 2511886.4, 5011872.3, 10000000]

vector = sx.GroupVector.Create(vmag, freq, sx.PhysicalType.VOLTS, sx.PhysicalType.HERTZ)
__bool__() bool

Returns True if the GroupVector object is valid. That is it represents a valid vector in the SIMetrix environment.

__init__(groupName: str = '', vectorName: str = '') GroupVector

Constructor. Constructs a GroupVector object. This can be used to create a GroupVector object that is known to already exist in SIMetrix or which will exist at some future time. Note that this does not create a vector in SIMetrix, only a reference to a vector in Python.

Parameters:
  • groupName (str) – Name of group that vector belongs to. If empty, the vector will be placed in the local group which is the context of the script that called Python. If set to “:”, the vector will be placed in the current group which is the group created by the most recent simulation, or the global group if no simulation has been run.

  • vectorName (str) – Name of vector

Example

vector = GroupVector("tran1", "VOUT")

The constructor can also be called with an empty string for the group name in which case the vector returned will be variable in the current script context. The current script context is the script that called Python:

vector = GroupVector("", "VOUT")
__repr__() str

Special Python method represents objects as a string. This is called in situations where a string is required or when explicitly cast to a string. The function will return a string in the form group:name. This can be passed in string form as an argument to SIMetrix commands that take a vector as an argument such as the Show and Curve commands.

assign(yval: npt.ArrayLike | str | float | simetrix.GroupVector, xval: npt.ArrayLike = None)

Assigns a value to a GroupVector. This can be used to pass data back to a SIMetrix script by assigning data to a known SIMetrix script variable.

Parameters:
  • yval (float array, complex array, string array, GroupVector) – Y-data assigned to GroupVector

  • xval (float array, complex array) – X-data. Optional but if present it must be the same length as yval

Example

import simetrix as sx

# var_a, var_b and var_c are names of SIMetrix script variables. If they do not exist already,
# the assign method will create them. They will then be accessible in the SIMetrix script that
# called the Python script
# the Python script
var_a = sx.GroupVector("", "var_a")
var_b = sx.GroupVector("", "var_b")
var_c = sx.GroupVector("", "var_c")

# Assign string to var_a
var_a.assign("RLOAD=50.0")

# Assign an XY vector to var_b
var_b.assign([1.2, 3.789, 10.3256], [0, 1e-6, 5e-6])

# Assign a string vector to var_c
var_c.assign(["R23", "C2", "Q1"])
property bool: bool

Scalar single division value. True if the value is non-zero otherwise False.

property complex: complex

Scalar single division value. Returns complex value if datatype is complex. Otherwise returns (0+0j).

property int: int

Scalar single division value. Returns integer value using floor() function if datatype is real. Otherwise returns 0

property name: str

Returns the name of the object.

property numDivisions: int

Returns the number of divisions.

property real: float

Scalar single division value. Returns real value if datatype is real. Otherwise returns 0.0.

property ref: str

Returns the name of the object prefixed with ‘@’. Used to pass the object by reference to a SIMetrix script. See simetrix.script.variable() for further information.

property string: str

Scalar single division value. Returns string value if datatype is string. Otherwise returns “”.

property stringdata: list[str]

String data.

property valid: bool

Returns true if the GroupVector is valid, that is it exists in the SIMetrix environment

property x: VectorData

VectorData object for x values.

property xcomplex: list[complex]

Complex x-data of division zero. If data is actually real, will return a complex value with imaginary part zero.

property xdata: list[float] | list[complex]

List of x values for division zero. See Accessing Data as Python Lists

property xreal: list[float]

Real x-data of division zero. If data is actually complex, will return the magnitude.

property y: VectorData

VectorData object for y values.

property ycomplex: list[complex]

Complex y-data of division zero. If data is actually real, will return a complex value with imaginary part zero.

property ydata: list[float] | list[complex]

List of y values for division zero. See Accessing Data as Python Lists

property yreal: list[float]

Real y-data of division zero. If data is actually complex, will return the magnitude.